package com.stox.client.ui.javafx.chartingy.model.shape;

import java.util.Date;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.geometry.Point2D;
import javafx.scene.control.Label;
import javafx.scene.shape.Line;

import com.stox.client.ui.javafx.chartingy.model.chart.Chart;
import com.stox.shared.core.util.Constant;

public class VerticalRay extends Shape {

	private final ControlPoint staticControlPoint;
	private final ControlPoint dynamicControlPoint;
	private final Label valueLabel = new Label();
	private final Line line = new Line();

	public VerticalRay(final Chart<?, ?> chart, final double initialSceneX, final double initialSceneY) {
		super(chart);
		staticControlPoint = new ControlPoint(chart, initialSceneX, initialSceneY);
		dynamicControlPoint = new ControlPoint(chart, initialSceneX, initialSceneY);

		line.startXProperty().bindBidirectional(line.endXProperty());
		line.startXProperty().bindBidirectional(staticControlPoint.centerXProperty());
		line.startYProperty().bindBidirectional(staticControlPoint.centerYProperty());
		staticControlPoint.centerXProperty().bindBidirectional(dynamicControlPoint.centerXProperty());
		staticControlPoint.centerXProperty().bindBidirectional(deletePoint.centerXProperty());
		deletePoint.centerYProperty().bind(line.endYProperty().subtract(deletePoint.radiusProperty()));
		deletePoint.centerXProperty().bindBidirectional(staticControlPoint.centerXProperty());
		valueLabel.layoutXProperty().bind(staticControlPoint.centerXProperty().subtract(valueLabel.widthProperty().divide(2)));
		valueLabel.layoutYProperty().bind(chart.primaryChart().getDateAxis().layoutYProperty());
		staticControlPoint.centerXProperty().addListener(new ChangeListener<Number>() {
			@Override
			public void changed(final ObservableValue<? extends Number> observable, final Number oldValue, final Number newValue) {
				valueLabel.setText(Constant.dateFormat.format(new Date(chart.primaryChart().getDateAxis().getValueForDisplay(newValue.doubleValue()))));
			}
		});

		line.setEndY(chart.getChartContentArea().getHeight());

		final ChangeListener<Number> directionListener = new ChangeListener<Number>() {

			private boolean down = true;

			@Override
			public void changed(final ObservableValue<? extends Number> observable, final Number oldValue, final Number newValue) {
				if ((dynamicControlPoint.getCenterY() >= staticControlPoint.getCenterY()) && !down) {
					line.endYProperty().unbind();
					deletePoint.centerYProperty().unbind();
					deletePoint.centerYProperty().bind(line.endYProperty().subtract(deletePoint.radiusProperty()));
					line.setEndY(chart.getChartContentArea().getHeight());
					line.endYProperty().bind(chart.getChartContentArea().heightProperty());
					down = true;
				} else if ((dynamicControlPoint.getCenterY() < staticControlPoint.getCenterY()) && down) {
					line.endYProperty().unbind();
					deletePoint.centerYProperty().unbind();
					deletePoint.centerYProperty().bind(line.endYProperty().add(deletePoint.radiusProperty()));
					line.setEndY(chart.getChartContentArea().getLayoutY());
					line.endYProperty().bind(chart.getChartContentArea().layoutYProperty());
					down = false;
				}
			}
		};

		dynamicControlPoint.centerYProperty().addListener(directionListener);
		staticControlPoint.centerYProperty().addListener(directionListener);

		final Point2D point = chart.getChartContentArea().sceneToLocal(initialSceneX, initialSceneY);
		staticControlPoint.setCenterX(point.getX());
		staticControlPoint.setCenterY(point.getY());
		dynamicControlPoint.setCenterY(point.getY());
		getChildren().addAll(staticControlPoint, dynamicControlPoint, line, deletePoint, valueLabel);
	}

	public ControlPoint getDynamicControlPoint() {
		return dynamicControlPoint;
	}

	@Override
	public void update() {
		staticControlPoint.update();
		dynamicControlPoint.update();
	}
	
	@Override
	public ControlPoint[] getControlPoints() {
		return new ControlPoint[]{staticControlPoint,dynamicControlPoint};
	}

}
